<?

class Ussd_Categories
{
    const dbtable = 'ussd_categories';
    var $categories=array();
    var $path=array();
    var $id;
    public function __construct() {
       $this->dbtable='ussd_categories';
    }

    // Create new category
    static public function create($data)
    {
       global $dbdefault;
       if (empty($data['category_name'])){
            return array('success'=>FALSE,'error'=>'Category name must not be empty!');
       }                
       $query = sprintf("INSERT INTO ".Ussd_Categories::dbtable." (category_name,category_content,parent_id,shortcode,category_priority) VALUES (%s,%s,%d,%s,%d)",
                        qs($data['category_name']),qs($data['category_content']),qs($data['parent_id']),qs($data['shortcode']),qs($data['category_priority'])
                     );
       mysql_query($query,$dbdefault) or die(__CLASS__."->".__METHOD__.":".mysql_error());       
       return array('success'=>TRUE,'category_id'=>mysql_insert_id());
    }

    // Update category
    static public function update($data)
    {
       global $dbdefault;
       $query=sprintf("UPDATE ".Ussd_Categories::dbtable."
                        SET category_name=%s,parent_id=%d,category_priority=%d,category_content=%s,shortcode=%s  WHERE category_id=%d",
                        quote_smart($data['category_name']),quote_smart($data['parent_id']),
			quote_smart($data['category_priority']),quote_smart($data['category_content']),quote_smart($data['shortcode']),
                        quote_smart($data['category_id'])
                        );
       mysql_query($query,$dbdefault) or die(__CLASS__."->".__METHOD__.":".mysql_error());
       return array('success'=>TRUE);
    }

    static public function get_category($category_id){
       global $dbdefault;
       $query = sprintf('SELECT * FROM '.Ussd_Categories::dbtable.' WHERE category_id=%d', $category_id);
       $res = mysql_query($query,$dbdefault) or die(__CLASS__."->".__METHOD__.":".mysql_error());
       if ($data=mysql_fetch_assoc($res)){
           return array('success'=>TRUE,'data'=>$data);           
       }else{
           return array('success'=>FALSE,'error'=>'Category does not exist!');
       }
    }
    
    static public function delete_category($category_id){
       global $dbdefault;
       $query = sprintf('DELETE FROM '.Ussd_Categories::dbtable.' WHERE category_id=%d', $category_id);
       $res = mysql_query($query,$dbdefault) or die(__CLASS__."->".__METHOD__.":".mysql_error());
        return array('success'=>TRUE);           
    }

    // Return the tree structure of categories from the current id
    // Current id = 0 mean open the whole structures
    public function open_categories_tree($id,$level=1,$itt=0)
    {
       $cats=array();
       $descendants=$categories[$id]['descendants']=$this->get_descendants($id);
       $cats[$itt]=array('id'=>$id,'level'=>$level,'descendants'=>$descendants);
       $children=$this->get_children($id);
       foreach ($children as $child_id)
       {
          $child=$this->open_categories_tree($child_id,$level+1,$itt+1);
          $cats=array_merge($cats,$child);
       }
       return $cats;
    }


    // Return the tree structure of categories from the current id
    // Current id = 0 mean open the whole structures$le
    public function browse_categories_tree($id)
    {
       $path=$this->get_path($id);
       $this->path=$path;
       $depth=count($path);
       if (!count($this->categories)) $this->get_full_list();
       $cats=$this->categories;
       $full_list=$this->open_categories_tree(0,0);
       foreach ($full_list as $item)
       {
          $id=$item['id'];
          if (in_array($cats[$id]['parent_id'],$path))
          {
             $return_arr[$id]=$item;
          }
       }
       return $return_arr;
    }

    // Get full lists of categories
    public function get_full_list(){
       	global $dbdefault;
        $categories=array();
       	$root=array('name'=>'root','parent_id'=>-1,'content'=>'');
       	$categories[0]=$root;
       	$query="SELECT * FROM ".Ussd_Categories::dbtable." ORDER BY category_priority";
       	$result=mysql_query($query,$dbdefault) or die(mysql_error());
       	while ($array=mysql_fetch_assoc($result)){
            $id=$array['category_id'];
            $categories[$id]=$array;
            $categories[$id]['name']=$array['category_name'];
            $categories[$id]['content']=$array['category_content'];
            $categories[$id]['parent_id']=$array['parent_id'];
	}
       	$this->categories=$categories;
        
        foreach($categories as $id=>$c){
            $categories[$id]['descendants']=$this->get_descendants($id);      
        }
       	$this->categories=$categories;
    }

    /* Navigation functions*/
    //Return the parent_id of current id
    public function get_parent($id)
    {
       if (!count($this->categories)) $this->get_full_list();
       if (array_key_exists($id,$this->categories))
           return $this->categories[$id]['parent_id'];
       else
           return -1;
    }

    //Return the list(array) of children categories id
    function get_children($id){
       	if (!count($this->categories)) $this->get_full_list();
       	$children=array();
       	foreach ($this->categories as $c_id=>$category){
           if ($category['parent_id']==$id) array_push($children,$c_id);
       	}
       	return $children;
    }

    //Return the list(array) of descendants categories id
    public function get_descendants($id){
       	$children=$this->get_children($id);
       	foreach ($children as $children_id){
            $grandchildren=$this->get_descendants($children_id);
            $children=array_merge($children,$grandchildren);
       	}
       	return $children;
    }

    //Return the root category from current category (id)
    public function get_root($id)
    {
       $pid=$this->get_parent($id);
       if ($pid==0)
          return $id;
       else
          return $this->get_root($pid);
    }

    //Return the categories having same parent as current categories
    function get_siblings($id)
    {
       $parent_id=$this->get_parent($id);
       $chilren=$this->get_children($parent_id);
       $siblings=array();
       foreach ($chilren as $child_id)
       {
          if ($child_id!=$id)
          array_push($siblings,$child_id);
       }
       return $siblings;
    }


    //Return the path from root to current category (id)
    function get_path($id)
    {
       $parent_id=$this->get_parent($id);
       if ($parent_id>=0)
       {
          $array=$this->get_path($parent_id);
          array_push($array,$id);
       }
       else
       {
          $array = array($id);
       }
       return $array;
    }

    
    // Exclusive for USSD services
    // Generate menu type respose by the customer
    // ex 1-2-1 mean the customer press node #1, then children node #2 of #1, then children node #1 of #2
    public function generate_response($id,$cur_res='')
    {
       global $dbdefault;
       $children=$this->get_children($id);
       $i=1;
       //echo "<br>$id:$cur_res";
       $query=sprintf("UPDATE ".Ussd_Categories::dbtable." SET response=%s  WHERE category_id=%d",
                        quote_smart($cur_res),quote_smart($id));
       mysql_query($query,$dbdefault) or die(__CLASS__."->".__METHOD__.":".mysql_error());

       foreach ($children as $child_id)
       {
           $res = (''==$cur_res) ? $i : $cur_res."-".$i  ;
           $this->generate_response($child_id,$res);
           $i++;
       }
    }

    

}

?>